/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package edu.cug.water.crawler.job.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.cug.water.crawler.common.utils.PageUtils;
import edu.cug.water.crawler.common.utils.Query;
import edu.cug.water.crawler.job.dao.ScheduleJobLogDao;
import edu.cug.water.crawler.job.entity.ScheduleJobLogEntity;
import edu.cug.water.crawler.job.service.ScheduleJobLogService;
import edu.cug.water.crawler.job.service.ScheduleJobService;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("scheduleJobLogService")
public class ScheduleJobLogServiceImpl extends ServiceImpl<ScheduleJobLogDao, ScheduleJobLogEntity> implements ScheduleJobLogService {

	@Autowired
	ScheduleJobService scheduleJobService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String jobId = (String)params.get("jobId");

		IPage<ScheduleJobLogEntity> page = this.page(
			new Query<ScheduleJobLogEntity>().getPage(params),
			new QueryWrapper<ScheduleJobLogEntity>().like(StringUtils.isNotBlank(jobId),"job_id", jobId).
					orderByDesc("create_time")
		);
		return new PageUtils(page);
	}

	@Override
	public void process(Long logId) {
		ScheduleJobLogEntity jobLog = this.getById(logId);
		jobLog.setIsProcessed(1);
		this.updateById(jobLog);
		scheduleJobService.run(new Long[]{jobLog.getJobId()});
	}

	@Override
	public Map statisticsWeekly() {
		List<ScheduleJobLogEntity> results = baseMapper.queryWeeklyLog();
		return dealData(results);
	}

	@Override
	public Map statisticsDay() {
		List<ScheduleJobLogEntity> results = baseMapper.queryDayLog();
		return dealData(results);
	}

	@Override
	public Map statisticsMonth() {
		List<ScheduleJobLogEntity> results = baseMapper.queryMonthLog();
		return dealData(results);
	}


	private Map dealData(List<ScheduleJobLogEntity> results) {
		Map<Long, List<ScheduleJobLogEntity>> listGroupBy = results.stream().filter(e -> e.getJobId() < 14).collect(Collectors.groupingBy(ScheduleJobLogEntity::getJobId));

		Map ans = new HashMap();

		Map res = new HashMap<String, StatisticVO>();

		long totalExecute = 0, totalErrorCnt = 0, totalNormalCnt = 0, totalCount = 0;
		for (Map.Entry<Long, List<ScheduleJobLogEntity>> entry: listGroupBy.entrySet()) {

			StatisticVO temp = new StatisticVO();
			Long jobId = entry.getKey();
			List<ScheduleJobLogEntity> items = entry.getValue();

			String jobName = items.get(0).getJobName();

			Map<Integer, List<ScheduleJobLogEntity>> itemsGroupByStatus = items.stream().collect(Collectors.groupingBy(ScheduleJobLogEntity::getStatus));

			// 任务失败次数 ， 成功次数
			List<ScheduleJobLogEntity> successfulJob = itemsGroupByStatus.get(0);

			int errorCnt = itemsGroupByStatus.containsKey(1) ? itemsGroupByStatus.get(1).size(): 0, normalCnt = successfulJob.size();
			// 入库的数据
			int count = successfulJob.stream().map(ScheduleJobLogEntity::getDataCnt).reduce(0, Integer::sum);


			totalErrorCnt += errorCnt;
			totalNormalCnt += normalCnt;
			totalCount += count;
			temp.setCount(count).setErrorCnt(errorCnt).setJobId(jobId).setJobName(jobName).setNormalCnt(normalCnt);
			res.put(jobName, temp);
		}

		JobTotalVO jobTotalVO = new JobTotalVO();
		jobTotalVO.setTotalCount(totalCount).setTotalErrorCnt(totalErrorCnt).setTotalNormalCnt(totalNormalCnt);

		ans.put("total", jobTotalVO);
		ans.put("groups", res);

		return ans;
	}

	@Data
	@Accessors(chain = true)
	class StatisticVO {
		String jobName;
		Long jobId;
		long execute;
		long errorCnt;
		long normalCnt;
		long count;
	}

	@Data
	@Accessors(chain = true)
	class JobTotalVO {
		long totalExecute;
		long totalErrorCnt;
		long totalNormalCnt;
		long totalCount;
	}

}
